(define vector-size 100)
(define hashfs '())
(define truth-list '())

(define new-bloom
  (lambda ()
    (let
	((v (make-vector vector-size)))
      (vector-fill! v #f)
      v)))

(define bloom-copy vector-copy)
(define value-in-bloom
;FIXME: numero de funcoes de hash nao variavel
  (lambda (v bloom)
    (equal?
      (map (lambda (k) (vector-ref bloom k)) (hash-values v))
      truth-list)))
    
(define add-to-bloom!
  (lambda (v bloom)
    (map (lambda (h)
	   (vector-set! bloom (h v) #t)) hashfs)
    bloom))

(define hash-values
  (lambda (v)
	   (pam hashfs v)))

(define set-hash-functions!
  (lambda (hs)
    (set! hashfs
	  (map  (lambda (h) (lambda (v) (modulo (h v) (1- vector-size)))) hs))
    (set! truth-list (make-list (length hashfs) #t))))

;pam = reverse map. toma uma lista de funcoes e aplica a um argumento
(define pam
  (lambda (fs x)
    (cond
     ((null? fs)
      '())
     (#t
      (cons ((car fs) x) (pam (cdr fs) x))))))  

(define generate-hash-functions
;recebe o numero de funcoes e uma funcao original. concatena aos valores
;originais na forma:
;f = "123"
;f1, f2, ... = ["1230", "12300", "123000"...]
  (lambda (n original)
    (letrec ((gen-hash
	      (lambda (n original current)
		(if (eq? n 0)
		    current
		    (gen-hash
		     (1- n)
		     original
		     (cons
		      (lambda (v)
			(string->number
			 ;concatena ao inicio da string
			 (string-pad-right (original v) (+ 15 n) #\0)
			 16)) ;lê em base 16
		      current))))))
      (gen-hash n original '()))))